package com.work.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.work.entity.User;
import com.work.expection.BizException;
import com.work.service.UserService;
import com.work.utils.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.work.constant.MQPrefixConstant.EMAIL_EXCHANGE;

/**
 * @Author: 星川
 * @Date: 2023/06/06/10:06
 * @Description:
 */

@RestController
@Log4j2
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;


    @Resource
    private RabbitTemplate rabbitTemplate;


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /*
     * 登录
     * */
    @PostMapping("/login")
    public ResultVo login(@RequestBody User user){
        System.out.println("我们接受到的信息为："+user);
        if (user!=null){
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//            验证登陆密码
            queryWrapper.lambda().eq(User::getUsername,user.getUsername()).eq(User::getPassword,user.getPassword());
            User one = userService.getOne(queryWrapper);
//            返回我们查询到的信息
            if (one != null){
                System.out.println("我们返回的信息为:"+one);
                return ResultUtils.success("登陆成功",one);
            }else {
                return ResultUtils.success("账号密码错误");
            }
        }else {
            return ResultUtils.success("未接受到账号密码");
        }
    }


//    /**
//     * 发送qq邮箱验证码短信
//     * @param user
//     * @return
//     */
//    @GetMapping("/sendMsg")
//    public ResultVo<String> sendMsg(@RequestBody User user, HttpSession session){
//        //获取邮箱
//        String email = user.getEmail();
//        if(StringUtils.isNotEmpty(email)){
//            //生成随机的4位验证码
//            String code = ValidateCodeUtils.generateValidateCode(4).toString();
//            log.info("code={}",code);
//            //调用自己封装的qq邮箱发送器发送邮箱
//            EmailUtil.sendAuthCodeEmail(email,code);
//            //需要将验证码保存到session中
//            session.setAttribute(email,code);
////            session.setMaxInactiveInterval(60); //设置session有效期 60秒,这里以后可能会用redis,所以先不设置！
//            return ResultUtils.success("邮箱验证码发送成功");
//        }
//        return ResultUtils.error("邮箱发送失败");
//    }

//    /**
//     * 这里的接收参数是phone和code,一般肯定单独创建一个dto来接收,这里直接其实使用map也可以
//     * @param map
//     * @param session
//     * @return
//     */
//    @PostMapping("/login")
//    public ResultVo<User> login(@RequestBody Map map, HttpSession session){
//        log.info(map.toString());
//        //获取邮箱
//        String email = map.get("email").toString();
//        //获取验证码
//        String code = map.get("code").toString();
//        //从Session中获取保存的验证码
//        Object codeInSession = session.getAttribute(email);
//        //进行验证码的比对(页面提交的验证码和Session中保存的验证码比对)
//        if(codeInSession!=null && codeInSession.equals(code)){
//            //如果能够比对成功,说明登录成功
//            //判断当前手机号对应的用户是否为新用户,如果是新用户就自动完成注册
//            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.eq(User::getEmail,email);
//            User user = userService.getOne(queryWrapper);
//            if(user==null){//说明是新用户
//                //直接注册
//                user = new User();
//                user.setEmail(email);
////                user.setStatus(1);
//                userService.save(user);
//            }
//            //登录成功,放入对应的用户session数据并返回对应用户的信息
//            session.setAttribute("user",user.getId());
//            log.info("user:::{}",user.getId());
//            return ResultUtils.success("登录成功",user);
//        }
//        return ResultUtils.error("登录失败");
//    }



    @GetMapping("/senCode")
    public ResultVo send(@RequestParam("phone") String phone){
        //校验次数
        if (RedisUtils.checkMaxPerDay(phone,stringRedisTemplate)){
            System.out.println("目前发送次数:" + stringRedisTemplate.opsForValue().get(RedisUtils.SEND_COUNT_KEY + phone));
//            throw new BizException("发送次数太多")
            return ResultUtils.success("已超过数量");
        }

        //校验频率
        if(RedisUtils.checkSendInterval(phone,stringRedisTemplate)){
            String s = stringRedisTemplate.opsForValue().get(RedisUtils.LAST_SEND_TIME_KEY + phone);
            Date date = new Date(Long.parseLong(s));
            System.out.println("上次发送时间" + date);
            return ResultUtils.error("发送速度过快");
        }
        //生成验证码
        int captcha = VerifyCodeUtil.generateVerifyCode(phone);
        String captchaKey =  RedisUtils.CAPTCHA_KEY + phone;
        //整合rabbitmq
        rabbitTemplate.convertAndSend(EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(captcha), new MessageProperties()));
        stringRedisTemplate.opsForValue().set(captchaKey, Integer.toString(captcha) , RedisUtils.EXPIRATION , TimeUnit.SECONDS);
        if(stringRedisTemplate.opsForValue().get(RedisUtils.SEND_COUNT_KEY+ phone) == null){
            stringRedisTemplate.opsForValue().set(RedisUtils.SEND_COUNT_KEY + phone , "1",1,TimeUnit.DAYS);
        }else {
            stringRedisTemplate.opsForValue().increment(RedisUtils.SEND_COUNT_KEY + phone , 1);
        }
        //更新验证码发送时间
        stringRedisTemplate.opsForValue().set(RedisUtils.LAST_SEND_TIME_KEY +phone , Long.toString(System.currentTimeMillis()));
        return ResultUtils.success("成功");
    }

    /**
     * 验证码登录
     * @param phone
     * @param code
     * @return
     */
    @RequestMapping("/loginByVerify")
    public ResultVo login(String phone , String code){
        String captcha = stringRedisTemplate.opsForValue().get(RedisUtils.CAPTCHA_KEY + phone);
        if(captcha == null){
          return   ResultUtils.error("验证码失效",400,"失败");

        }
        if(!captcha.equals(code)){
          return   ResultUtils.error("验证码错误",500,"错误");

        }

        return ResultUtils.success("登录成功",200,"成功");

    }


    /**
     * 注册
     * @param user
     * @return
     */
    @PostMapping("/register")
    public ResultVo<User> register(@RequestBody User user){
        boolean b = userService.saveOrUpdate(user);
        if(b){
            return ResultUtils.success("注册成功",200);
        }else {
           // throw new BizException("注册失败");
            return ResultUtils.error("注册失败",500);
        }

    }

}


